package com.ruicar.afs.cloud.workflow.greatwall.processor.impl.objcode;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.ruicar.afs.cloud.common.core.constant.CommonConstants;
import com.ruicar.afs.cloud.common.core.dynamicrequest.DynamicRequest;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.workflow.api.dto.afsprocess.request.AfsFlowQueryRequest;
import com.ruicar.afs.cloud.workflow.api.dto.afsprocess.request.UpdateBizDataRequest;
import com.ruicar.afs.cloud.workflow.api.dto.afsprocess.response.UpdateBizDataResponse;
import com.ruicar.afs.cloud.workflow.api.enums.FlowStatus;
import com.ruicar.afs.cloud.workflow.api.util.FlowMappingHelper;
import com.ruicar.afs.cloud.workflow.greatwall.dto.GwtRequest;
import com.ruicar.afs.cloud.workflow.greatwall.entity.AfsGreatWallWorkflowBizData;
import com.ruicar.afs.cloud.workflow.greatwall.entity.AfsGreatWallWorkflowMappingInfo;
import com.ruicar.afs.cloud.workflow.greatwall.enums.GwtMsgType;
import com.ruicar.afs.cloud.workflow.greatwall.enums.GwtObjectCode;
import com.ruicar.afs.cloud.workflow.greatwall.enums.RequestPath;
import com.ruicar.afs.cloud.workflow.greatwall.processor.GwfObjectCodeProcessor;
import com.ruicar.afs.cloud.workflow.greatwall.service.AfsGreatWallWorkflowBizDataService;
import com.ruicar.afs.cloud.workflow.greatwall.service.AfsGreatWallWorkflowMappingInfoService;
import com.ruicar.afs.cloud.workflow.greatwall.service.AfsGreatWallWorkflowNoticeExceptionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;

import static com.ruicar.afs.cloud.workflow.api.constant.FlowConstant.FLOW_EXCEPTION_DESC_KEY;


/**
 * The type DefaultUpdateBizDataProcessor
 * <p>Description: </p>
 *
 * @author Fzero
 * @version 1.0
 * @date Created on 2020.07.10 21:22:47
 * @since 1.0
 */
@Component
@Slf4j
public class DefaultUpdateBizDataProcessor extends AbsGwfNoticeProcessor implements GwfObjectCodeProcessor {

    /**
     * Afs great wall workflow mapping info service
     * <p>Description: </p>
     */
    private final AfsGreatWallWorkflowMappingInfoService afsGreatWallWorkflowMappingInfoService;
    /**
     * Afs great wall workflow notice exception service
     * <p>Description: </p>
     */
    private final AfsGreatWallWorkflowNoticeExceptionService afsGreatWallWorkflowNoticeExceptionService;
    /**
     * Dynamic request
     * <p>Description: </p>
     */
    private final DynamicRequest dynamicRequest;

    public DefaultUpdateBizDataProcessor(AfsGreatWallWorkflowBizDataService afsGreatWallWorkflowBizDataService, AfsGreatWallWorkflowNoticeExceptionService afsGreatWallWorkflowNoticeExceptionService, AfsGreatWallWorkflowMappingInfoService afsGreatWallWorkflowMappingInfoService, AfsGreatWallWorkflowNoticeExceptionService afsGreatWallWorkflowNoticeExceptionService1, DynamicRequest dynamicRequest) {
        super(afsGreatWallWorkflowBizDataService, afsGreatWallWorkflowNoticeExceptionService);
        this.afsGreatWallWorkflowMappingInfoService = afsGreatWallWorkflowMappingInfoService;
        this.afsGreatWallWorkflowNoticeExceptionService = afsGreatWallWorkflowNoticeExceptionService1;
        this.dynamicRequest = dynamicRequest;
    }

    /**
     * Belong msg gwt msg type
     *
     * @return the gwt msg type
     */
    @Override
    public GwtMsgType belongMsg() {
        return GwtMsgType.UPDATE_BIZ_DATA;
    }

    /**
     * Object code gwt object code
     *
     * @return the gwt object code
     */
    @Override
    public GwtObjectCode objectCode() {
        return GwtObjectCode.NONE;
    }

    /**
     * Process string
     *
     * @param request request
     * @return the string
     */
    @Override
    public String process(GwtRequest request) {
        log.info("业务状态变更通知======>{}", request);
        checkException(request.getServiceId(), request.getDataId());
        AfsGreatWallWorkflowBizData afsGreatWallWorkflowBizData = afsGreatWallWorkflowBizDataService.getBizDataObjServiceIdAndDataId(request.getServiceId(), request.getDataId());
        AfsGreatWallWorkflowMappingInfo afsGreatWallWorkflowMappingInfo = afsGreatWallWorkflowMappingInfoService.queryMappingByServiceId(request.getServiceId());
        UpdateBizDataResponse updateBizDataResponse = new UpdateBizDataResponse();
        try {
            if (afsGreatWallWorkflowMappingInfo != null) {
                if (noticeBiz(request, afsGreatWallWorkflowMappingInfo)) {
                    updateBizDataResponse.setSuccess(true);
                } else {
                    if (afsGreatWallWorkflowBizData != null) {
                        saveException(request, afsGreatWallWorkflowBizData.getFlowInstanceId(), (genExceptionCheckCode(MessageFormat.format("{0}-{1}-{2}", request.getServiceId(), request.getDataId(), request.getBody()))));
                        afsGreatWallWorkflowBizData.setFlowStatus(FlowStatus.ERROR);
                        afsGreatWallWorkflowBizDataService.updateById(afsGreatWallWorkflowBizData);
                    }
                    updateBizDataResponse.setSuccess(false);
                }
            } else {
                throw new AfsBaseException("通知数据失败");
            }
        } catch (Exception e) {
            if (afsGreatWallWorkflowBizData != null) {
                saveException(request, afsGreatWallWorkflowBizData.getFlowInstanceId(), (genExceptionCheckCode(MessageFormat.format("{0}-{1}-{2}", request.getServiceId(), request.getDataId(), request.getBody()))));
                afsGreatWallWorkflowBizData.setFlowStatus(FlowStatus.ERROR);
                String bizData="{}";
                if(StringUtils.isNotEmpty(afsGreatWallWorkflowBizData.getBizData())){
                    bizData = afsGreatWallWorkflowBizData.getBizData();
                }
                JSONObject bizDataJson = JSONObject.parseObject(bizData);
                bizDataJson.put(FLOW_EXCEPTION_DESC_KEY,"更新业务数据异常");
                afsGreatWallWorkflowBizDataService.updateById(afsGreatWallWorkflowBizData);
            }
            throw e;
        }
        return JSONObject.toJSONString(updateBizDataResponse);
    }

    @Override
    public boolean processError(GwtRequest request) {
        AfsGreatWallWorkflowMappingInfo afsGreatWallWorkflowMappingInfo = afsGreatWallWorkflowMappingInfoService.queryMappingByServiceId(request.getServiceId());
        if (afsGreatWallWorkflowMappingInfo != null) {
            try {
                return noticeBiz(request, afsGreatWallWorkflowMappingInfo);
            } catch (Exception e) {
                return false;
            }
        } else {
            return false;
        }
    }

    private boolean noticeBiz(GwtRequest request, AfsGreatWallWorkflowMappingInfo afsGreatWallWorkflowMappingInfo) {
        try {
            AfsFlowQueryRequest<UpdateBizDataRequest> afsFlowQueryRequest = new AfsFlowQueryRequest<>();
            afsFlowQueryRequest.setAfsFlowKey(afsGreatWallWorkflowMappingInfo.getAfsFlowKey());
            UpdateBizDataRequest updateBizDataRequest = new UpdateBizDataRequest();
            updateBizDataRequest.setConfigData(request.getBody());
            updateBizDataRequest.setServiceId(request.getServiceId());
            updateBizDataRequest.setBizDataId(request.getDataId());
            updateBizDataRequest.setAfsFlowKey(FlowMappingHelper.getAfsKey(request.getServiceId()));
            afsFlowQueryRequest.setData(updateBizDataRequest);
            IResponse<UpdateBizDataResponse> response =
                    dynamicRequest.post(afsGreatWallWorkflowMappingInfo.getServiceName(), AfsEnumUtil.key(RequestPath.UPDATE_BIZ_DATA), afsFlowQueryRequest, new TypeReference<UpdateBizDataResponse>() {
                    });
            return CommonConstants.SUCCESS.equalsIgnoreCase(response.getCode()) && response.getData().isSuccess();
        } catch (Exception e) {
            log.error("通知业务端失败", e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public String processKey() {
        return MessageFormat.format("{0}-{1}", AfsEnumUtil.key(belongMsg()), AfsEnumUtil.key(objectCode()));
    }
}
